﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace SimdTest2.Methods
{
    [Algorithm(true, AlgorithmType.Seven)]
    public unsafe class SevenMethod : AlgorithmBase
    {
        public SevenMethod(int row, int col) : base(row, col)
        {
        }
        int[] _data;
        protected override void CreateData()
        {
            _data = new int[_size];
            Random random = new Random();
            for (int i = 0; i < _data.Length; i++)
            {
                _data[i] = random.Next(1, 999999);
            }
        }
        protected override void OrdinaryMethod()
        {
            var value = _data[0];
            for (var i = 1; i < _data.Length; i++)
            {
                var _value = _data[i];
                if (_value > value)
                {
                    value = _value;
                }
            }
        }

        protected override void SimdMethod()
        {
            int vectorSize = Vector128<int>.Count;
            int limit = _data.Length - (_data.Length&(vectorSize-1));

            fixed (int* pArray = _data)
            {
                int maxElement = *pArray;
                Vector128<int> vectorMax = *(Vector128<int>*)(pArray);
                for (int i = 1; i < limit; i += vectorSize)
                {
                    vectorMax = Sse41.Max(vectorMax, *(Vector128<int>*)(pArray + i));
                }
                int* maxPtr = (int*)&vectorMax;
                for (int j = 0; j < vectorSize; j++)
                {
                    maxElement = Math.Max(maxElement, *(maxPtr + j));
                }
                for (int i = limit; i < _data.Length; i++)
                {
                    maxElement = Math.Max(maxElement, *(pArray + i));
                }
            }
        }
    }
}
